package logger

import (
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gorm.io/gorm/logger"

	"project/study-go/config"
)

var (
	//controller日志对象
	AccessLogger *zap.SugaredLogger

	//服务器例程日志对象
	RoutineLogger *zap.SugaredLogger

	//DB操作的日志对象
	DBLogger *ormLogger

	//一些不期望的的错误日志对象
	UnexpectLogger *zap.SugaredLogger
)

func init() {
	//create server RoutineLogger
	{
		conf := NewProductionConfig(config.Vip.GetString("zap.RoutineLogger.Encoding"),
			config.Vip.GetStringSlice("zap.RoutineLogger.OutputPaths"))
		conf.DisableCaller = false
		Logger, err := conf.Build()
		if err != nil {
			panic(err)
		}
		RoutineLogger = Logger.Sugar()
	}

	//create AccessLogger
	{
		conf := NewProductionConfig(config.Vip.GetString("zap.AccessLogger.Encoding"),
			config.Vip.GetStringSlice("zap.AccessLogger.OutputPaths"))
		Logger, err := conf.Build()
		if err != nil {
			panic(err)
		}
		AccessLogger = Logger.Sugar()
	}

	//create DBLogger
	{
		conf := NewProductionConfig(config.Vip.GetString("zap.ORMLogger.Encoding"),
			config.Vip.GetStringSlice("zap.ORMLogger.OutputPaths"))
		Logger, err := conf.Build()
		if err != nil {
			panic(err)
		}
		suagr := Logger.Sugar()
		DBLogger = NewOrmLogger(suagr, logger.Config{
			SlowThreshold: time.Millisecond * 100,
			LogLevel:      logger.LogLevel(config.Vip.GetInt("zap.ORMLogger.logLevel")),
		})
	}

	//create UnexceptLogger (only extra error caller)
	{
		conf := NewProductionConfig(config.Vip.GetString("zap.UnexpectLogger.Encoding"),
			config.Vip.GetStringSlice("zap.UnexpectLogger.OutputPaths"))
		//禁用调用者信息：否
		conf.DisableCaller = false
		Logger, err := conf.Build()
		if err != nil {
			panic(err)
		}
		UnexpectLogger = Logger.Sugar()
	}
}

func Flush() {
	AccessLogger.Sync()
	RoutineLogger.Sync()
}

//NewProductionConfig 生成zap的日志配置
func NewProductionConfig(encoding string, outputPaths []string) zap.Config {
	conf := zap.Config{
		Level:             zap.NewAtomicLevelAt(zap.InfoLevel),
		Development:       false,
		Sampling:          nil,
		DisableCaller:     true,
		DisableStacktrace: true,
		Encoding:          encoding,
		EncoderConfig:     NewProductionEncoderConfig(),
		OutputPaths:       outputPaths,
		ErrorOutputPaths:  nil,
		InitialFields:     nil,
	}

	return conf

}

//NewProductionEncoderConfig 生成zap的日志编码配置
func NewProductionEncoderConfig() zapcore.EncoderConfig {
	return zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		FunctionKey:    zapcore.OmitKey,
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeTime:     zapcore.TimeEncoderOfLayout("2006/01/02 - 15:04:05"),
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	}
}
